Projekt z Analizy Danych - Siłownia

Aleksandra Ochocińska

Mateusz Wasiewski

Adam Sienkiewicz

Wprowadzenie

1. Wstęp

2. Zmienne w zbiorze danych

Wiek - wiek użytkownika siłowni.

Płeć - płeć użytkownika siłowni.

Waga - waga użytkownika siłowni w kilogramach.

Wzrost - wzrost użytkownika siłowni w metrach

Max_BPM - maksymalne tętno podczas sesji treningowych.

Avg_BPM - średnie tętno podczas sesji treningowych.

Resting_BPM - tętno w spoczynku przed treningiem.

Session_Duration - czas trwania każdej sesji treningowej w godzinach.

Calories_Burned - całkowita liczba kalorii spalonych podczas każdej sesji.

Workout_Type - rodzaj wykonanego treningu (np. kardio, siłowy, joga, HIIT).

Fat_Percentage -procent tkanki tłuszczowej.

Water_Intake - dzienne spożycie wody podczas treningu w litrach.

Workout_Frequency - liczba sesji treningowych w tygodniu.

Experience_Level - poziom doświadczenia, od początkującego (1) do eksperta (3).

BMI - wskaźnik masy ciała, obliczany na podstawie wzrostu i wagi.

3. Struktura danych

Nazwa zbioru danych silownia
Liczba wierszy 973
Liczba kolumn 15
_______________________
Częstość typów kolumn:
Kolumny typu tekstowego 2
Kolumny typu liczbowego 13
________________________

Kolumny typu tekstowego

Kolumna Brakujące wartości Kompletność Min Max Puste Unikalne wartości Whitespace
Gender 0 1.00 4 6 0 2 0
Workout_Type 150 0.85 4 8 0 4 0

Kolumny typu liczbowego

Kolumna Brakujące wartości Kompletność Średnia Odchylenie standardowe 0 Percentyl 25 Percentyl 50 Percentyl 75 Percentyl 100 Percentyl Histogram
Age 100 0.90 38.63 12.27 18.00 28.00 39.00 50.00 59.00 ▇▆▆▇▇
Weight (kg) 0 1.00 73.85 21.21 40.00 58.10 70.00 86.00 129.90 ▅▇▅▂▂
Height (m) 0 1.00 1.72 0.13 1.50 1.62 1.71 1.80 2.00 ▅▇▇▃▃
Max_BPM 0 1.00 179.88 11.53 160.00 170.00 180.00 190.00 199.00 ▇▇▇▇▇
Avg_BPM 0 1.00 143.77 14.35 120.00 131.00 143.00 156.00 169.00 ▇▇▆▆▆
Resting_BPM 0 1.00 62.22 7.33 50.00 56.00 62.00 68.00 74.00 ▇▆▇▇▇
Session_Duration (hours) 0 1.00 1.26 0.34 0.50 1.04 1.26 1.46 2.00 ▂▅▇▃▂
Calories_Burned 0 1.00 905.42 272.64 303.00 720.00 893.00 1076.00 1783.00 ▃▇▇▂▁
Fat_Percentage 0 1.00 24.98 6.26 10.00 21.30 26.20 29.30 35.00 ▂▂▅▇▅
Water_Intake (liters) 0 1.00 2.63 0.60 1.50 2.20 2.60 3.10 3.70 ▃▆▇▃▆
Workout_Frequency (days/week) 0 1.00 3.32 0.91 2.00 3.00 3.00 4.00 5.00 ▅▇▁▆▂
Experience_Level 0 1.00 1.81 0.74 1.00 1.00 2.00 2.00 3.00 ▇▁▇▁▃
BMI 150 0.85 24.82 6.60 12.32 20.10 23.94 28.45 47.72 ▃▇▅▁▁

4. Wstępne przygotowanie danych

Przed rozpocząciem procesu Data Wranglingu pobraliśmy i zainstalowaliśmy wszystkie niezbędne pakiety potrzebne do naszej analizy. Kolejnym krokiem była zmiana nazw kolumn z :

  • Weight (kg) na Weight_kg

  • Height (m) na Height_m

  • Session_Duration (hours) na Session_Duration_hours

  • Water_Intake (liters) na Water_Intake_liters

  • Workout_Frequency (days/week) na Workout_Frequency_daysweek

Data Wrangling

1. Obserwacje odstające

Obserwacje odstające to dane, które znacząco różnią się od reszty zbioru, co może wynikać z błędów pomiaru, specyfiki badanego zjawiska lub innych nietypowych czynników. W celu poznania obserwacji odstających w naszym zbiorze danych zastowaliśmy wykres ramkowy (box plot), pozwalający na wizualne wykrycie wartości wykraczających poza typowy zakres danych.

Age

Zmienna Age nie posiada obserwacji odstających.

Weight

Zmienna Weight posiada odstające obserwacje (górne outliery), czyli obserwacje, które znajdują się o więcej niż 1,5 rozstępu ćwiartkowego powyżej trzeciego kwartyla.

Height

Zmienna Height nie ma obserwacji odstających.

MaxBPM

Zmienna MaxBPM nie posiada obserwacji odstających.

AvgBPM

Zmienna AvgBPM nie ma obserwacji odstających.

RestingBPM

Zmienna RestingBPM nie ma obserwacji odstających.

Session Duration

Zmienna Session Duration nie posiada obserwacji odstających.

Calories Burned

Zmienna Calories Burned posiada górne outliery, czyli obserwacje, które znajdują się o więcej niż 1,5 rozstępu ćwiartkowego powyżej trzeciego kwartyla.

Fat Percentage

Zmienna Fat Percentage nie ma obserwacji odstających.

Water Intake

Zmienna Water Intake nie posiada obserwacji odstających.

Workout Frequency

Zmienna Workout Frequency nie posiada obserwacji odstających.

BMI

W przypadku zmiennej BMI występują górne outliery, czyli obserwacje, które znajdują się o więcej niż 1,5 rozstępu ćwiartkowego powyżej trzeciego kwartyla.

Podsumowanie

Za pomocą wykresu ramkowego wykazano, że w przypadku zmiennych Weight, Calories_Burned oraz BMI występują górne outliery,czyli obserwacje, które znajdują się o więcej niż 1,5 rozstępu ćwiartkowego powyżej trzeciego kwartyla. Żadna zmienna natomiast nie posiada ekstremalnych obserwacji odstających.

2. Analiza braków danych

Analiza braków danych jest kluczowym etapem przygotowania zbioru danych do dalszej analizy. W ramach tego procesu określimy liczbę braków w zbiorze, przeanalizujemy ich rozmieszczenie oraz sprawdzimy, czy występują korelacje między brakami w różnych zmiennych. Wyniki tej analizy posłużą jako podstawa do podjęcia decyzji o dalszym postępowaniu z brakującymi danymi.

Wstępna analiza braków danych

Sprawdzenie gdzie występują braki danych i procentowo ile ich jest

W całej bazie danych brakuje 2,7% danych.

Braki danych występują w kolumnie Workout_Type, Age oraz BMI.

Ile braków jest w poszczególnych kolumnach

Kolumna Age ma 100 braków.

Kolumna Workout_Type ma 150 braków.

Kolumna BMI ma 150 braków.

Występowanie braków w wierszach

Liczba NA w wierszu Liczba wierszy Procent wszystkich wierszy
0 631 64,85%
1 287 29,50%
2 52 5,34%
3 3 0,31%

631 wierszy ma 0 NA

287 wierszy ma 1 NA

  • 115 w Workout_Type

  • 106 w BMI

  • 66 w Age

52 wiersze ma 2 NA

  • 21 wierszy w Workout_Type i BMI

  • 20 wierszy w Age i BMI

  • 11 w Age i Workout_Type

3 wiersze mają 3 NA

Sprawdzanie korelacji między brakami danych

1. Age i BMI

Braki w kolumnie BMI są całkowicie niezależne od wartości w kolumnie Age.

Z kolei braki w kolumnie Age są raczej niezależne od wartości BMI, choć zauważono nieco większą liczbę braków w przypadku niższych wartości BMI.

2. Workout_Type i BMI

Braki w kolumnie BMI są całkowicie niezależne od wartości w kolumnie Workout_Type.

Z kolei braki w kolumnie Workout_Type są raczej niezależne od wartości BMI, choć zauważono nieco większą liczbę braków w przypadku niższych wartości BMI.

3. Workout_Type i Age

Braki w obu kolumnach są całkowicie niezależne od siebie.

3. Imputacja braków danych

W procesie analizy braków danych napotkaliśmy na brakujące wartości (NA) w kolumnach Age, BMI oraz Workout_Type. Aby zapewnić spójność i pełność danych, postanowiliśmy przeprowadzić imputację braków, czyli zastąpienie brakujących wartości odpowiednimi danymi.

Kolumna BMI

Braki w kolumnie postanowaliśmy zastąpić za pomocą wzoru na BMI.

\[ BMI = \frac{waga}{wzrost^2} \]

silownia$BMI <- ifelse(
  is.na(silownia$BMI),  
  silownia$Weight_kg / (silownia$Height_m^2),  
  silownia$BMI )

Wybraliśmy wzór na BMI jako metodę uzupełniania braków, ponieważ opiera się on na dwóch kluczowych zmiennych: wadze i wzroście, które w naszym zbiorze danych są kompletne. Dzięki temu obliczenie BMI za pomocą wzrou jest najbardziej rzetelną metodą imputacji, gdyż wykorzystuje dostępne, pełne informacje do oszacowania brakujących wartości.

Kolumna Workout_Type i Age

W przypadku kolumnt Workout_Type i Age zdecydowaliśmy przeprowadzić imputację na kilka sposób, a następnie wybrać najlepszą możliwość.

1. Imputacja metodą k-Nearest Neighbors (kNN)

silownia_kNN <- kNN(silownia, k = 3)

2. Imputacja z pakietem Mice

if (!is.factor(silownia$Workout_Type)) {
  silownia$Workout_Type <- factor(silownia$Workout_Type, levels = c("Yoga", "Cardio", "HIIT", "Strength"))
}

metody <- make.method(silownia)

metody["Age"] <- "pmm"
metody["Workout_Type"] <- "polyreg"
metody["BMI"] <- "" 

pred_mat <- make.predictorMatrix(silownia)
pred_mat["BMI", ] <- 0 # Wyłącz imputację dla BMI
pred_mat[, "BMI"] <- 1 # BMI jako predyktor dla innych kolumn

silownia_imp <- mice(silownia, m = 5, method = metody, predictorMatrix = pred_mat, seed = 123)

lm_imp <- with(silownia_imp, lm(BMI ~ Weight_kg + Gender))
lm_pooled <- pool(lm_imp)

summary(lm_pooled, conf.int = TRUE, conf.level = 0.95)

stripplot(silownia_imp, BMI ~ Weight_kg | .imp, pch = 20, cex = 2)

silownia_mice <- complete(silownia_imp, action = 1)

3. Imputacja hot-deck

silownia_hotdeck <- hotdeck(silownia)

4. Imputacja RPART

silownia_rpart  <- silownia  %>%
  mutate(Workout_Type = case_when(
    Workout_Type == "Yoga" ~ 1,
    Workout_Type == "Cardio" ~ 2,
    Workout_Type == "HIIT" ~ 3,
    Workout_Type == "Strength" ~ 4,
    TRUE ~ as.numeric(Workout_Type) 
  ))

silownia_rpart <- silownia_rpart %>%
  mutate(Gender = case_when(
    Gender == "Male" ~ 1,
    Gender == "Female" ~ 2,
    TRUE ~ as.numeric(Gender) 
  ))


drzewo_decyzyjne1 <- rpart(Workout_Type ~ Age + BMI + Max_BPM + Weight_kg + Height_m + Avg_BPM + Resting_BPM + 
                             Session_Duration_hours + Calories_Burned + 
                             Fat_Percentage + Water_Intake_liters + 
                             Workout_Frequency_daysweek + Gender + Experience_Level, data = silownia_rpart, method = "anova", na.action = na.exclude)

silownia_rpart$Workout_Type[is.na(silownia_rpart$Workout_Type)] <- predict(drzewo_decyzyjne1, newdata = silownia_rpart[is.na(silownia_rpart$Workout_Type), ])


drzewo_decyzyjne2 <- rpart(Age ~ BMI + Workout_Type + Gender + Max_BPM + Weight_kg + Height_m + Avg_BPM + Resting_BPM + 
                             Session_Duration_hours + Calories_Burned + 
                             Fat_Percentage + Water_Intake_liters + 
                             Workout_Frequency_daysweek + Experience_Level, data = silownia_rpart, method = "anova", na.action = na.exclude)
silownia_rpart$Age[is.na(silownia_rpart$Age)] <- predict(drzewo_decyzyjne2, newdata = silownia_rpart[is.na(silownia_rpart$Age), ])

Wybór metody

Zdecydowaliśmy się zastąpić braki danych występujące w kolumnach Age i Workout_Type za pomocą metody hot-deck, ponieważ jest to podejście, które pozwala na imputację brakujących wartości w sposób uwzględniający podobieństwo do istniejących danych. Dzięki tej metodzie wartości brakujące są zastępowane rzeczywistymi danymi z innych obserwacji o podobnych cechach,

4. Walidacja danych

Po zakończeniu procesu uzupełniania braków w naszych danych, kolejnym krokiem w przygotowywaniu ich do dalszej analizy jest ich walidacja. Ten etap pozwala sprawdzić czy dane, są wolne od błędów, niespójności i nieścisłości, które mogłyby negatywnie wpłynąć na dalszą pracę z nimi. Walidacja danych obejmuje zarówno sprawdzenie poprawności logicznej, strukturalnej, jak i identyfikację potencjalnych anomalii czy niezgodności z przyjętymi założeniami.

Age

Wartości w kolumnie Age powinny być liczbami całkowitymi mieszczącymi się w przedziale od 0 do 110 włącznie.

Gender

Kolumna gender przyjmuje wartość Female albo Male.

Weight

Wartości w kolumnie Weight_kg powinny być liczbami mieszczącymi się w przedziale od 40 kg do 140 kg włącznie.

Height

W kolumnie Height_m powinny znajdować się wartości liczbowe z zakresu od 1.30 m do 2.15 m włącznie.

MaxBPM

Kolumna MaxBPM musi posiadać wartości, które są liczbami z zakresu od 110 do 210 włącznie.

AvgBPM

Wartości w kolumnie Avg_BPM powinny być liczbami mieszczącymi się w przedziale od 80 do 180 włącznie.

RestingBPM

W kolumnie Resting_BPM powinny znajdować się wartości liczbowe z zakresu od 45 do 130 włącznie.

Session Duration

Wartości w kolumnie Session Duration powinny być dodatnimi liczbami nieprzekraczającymi 2.

Calories Burned

Wartości powinny być dodatnimi liczbami nieprzekraczającymi 2000.

Workout Type

Kolumna Workout_Type powinna zawierać tylko takie wartości jak: Yoga, Cardio, HIIT oraz Strength.

Fat Percentage

Wartości w kolumnie Fat_Percentage powinny być liczbami dodatnimi nieprzekraczającymi 50.

Water Intake

Wartości powinny być liczbami dodatnimi nieprzekraczającymi 4.

Workout Frequency

Kolumna Workout Frequency powinna zawierać tylko takie wartości jak: 0, 1, 2, 3, 4, 5, 6, 7.

Experience Level

Kolumna Experience Level powinna zawierać tylko takie wartości jak: 0, 1, 2, 3.

BMI

Wartości w kolumnie BMI powinny być dodatnimi liczbami mieszczącymi się w przedziale od 10 do 60 włącznie, a ich różnica względem wartości obliczonej jako Weight_kg/Height_m^2 powinna być mniejsza niż 0.1.”

Podsumowanie

W naszym zbiorze danych nie wystąpiły żadne błędy, więc jest on gotowy do przeprowadzenie wizualizacji oraz dalszej analizy.

Wizualizacja danych

Analiza opisowa

Wnioskowanie

Podsumowanie